package config

import (
	"encoding/json"
	"fmt"
	"sync"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

// 定义程序配置
// dsn := "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
// 凡是可以提出出配置的

// 程序的配置对象
type Config struct {
	App   *App   `json:"app"`
	MySQL *MySQL `json:"mysql"`
	Log   *Log   `json:"log"`
}

// &{0x102317ec0 0x10231c8a0}
//
//	String() string, fmt.Strigger接口
//
// fmt.
func (c *Config) String() string {
	v, _ := json.Marshal(c)
	return string(v)
}

// app:
//
//	host: 127.0.0.1
//	port: 8080
type App struct {
	Host string `json:"host"`
	Port int    `json:"port"`
}

func (c *App) Address() string {
	return fmt.Sprintf("%s:%d", c.Host, c.Port)
}

// mysql:
//
//	host: 127.0.0.1
//	port: 3306
//	database: test
//	username: "root"
//	password: "123456"
//	debug: true
type MySQL struct {
	Host     string `json:"host"`
	Port     int    `json:"port"`
	Database string `json:"database"`
	Username string `json:"username"`
	Password string `json:"password"`
	Debug    bool   `json:"debug"`

	db   *gorm.DB
	lock sync.Mutex
}

// 初始化数据库, 能过与数据库交互的 连接池对象: db
// 复用, 只要有就用 之前的，没有才初始化新的db对象
func (c *MySQL) DB() *gorm.DB {
	c.lock.Lock()
	defer c.lock.Unlock()

	if c.db == nil {
		dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local",
			c.Username,
			c.Password,
			c.Host,
			c.Port,
			c.Database,
		)
		db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
		if err != nil {
			panic("failed to connect database")
		}

		if c.Debug {
			db = db.Debug()
		}
		c.db = db
	}

	return c.db
}
